package com.mszl.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mszl.blog.dao.ArticleBodyDao;
import com.mszl.blog.dao.ArticleTagDao;
import com.mszl.blog.entity.Article;
import com.mszl.blog.dao.ArticleDao;
import com.mszl.blog.entity.ArticleBody;
import com.mszl.blog.entity.ArticleTag;
import com.mszl.blog.entity.Category;
import com.mszl.blog.service.*;
import com.mszl.blog.utils.ThreadLocalUtil;
import com.mszl.blog.vo.*;
import com.mszl.blog.vo.params.ArticleParam;
import com.mszl.blog.vo.params.PageParams;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
//import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.transaction.annotation.Transactional;
import com.mszl.blog.entity.User;


/**
 * (Article)表服务实现类
 *
 * @author makejava
 * @since 2025-07-31 23:12:06
 */
@Service("articleService")
public class ArticleServiceImpl implements ArticleService {
    @Resource
    private ArticleDao articleDao;
    @Resource
    private TagService tagService;
    @Resource
    private UserService userService;
    @Resource
    private ArticleBodyService articleBodyService;
    @Resource
    private CategoryService categoryService;
    @Resource
    private ArticleTagDao articleTagDao;

    /**
     * pageParams的参数中没有CategoryId和tagId时，为首页的文章展示
     * 有CategoryId和tagId时，为分类下的文章展示
     * @param pageParams
     * @return
     */

    @Override
    public Result listArticle(PageParams pageParams){
/*       分页查询article数据库
            用了mybatis-plus的分页，把创建的pageParams传入
            根据接口需要的data
            生成了articleVo，存入在result里的data中返回
* */
        Page<Article> page=new Page<Article>(pageParams.getPage(),pageParams.getPageSize());

        LambdaQueryWrapper<Article> queryWrapper=new LambdaQueryWrapper<>();//包裹
        if(pageParams.getCategoryId()!=null){
            queryWrapper.eq(Article::getCategoryId,pageParams.getCategoryId());
            //and category_id=#{categoryId}
        }
        List<Long> articleIdList=new ArrayList<>();
        if(pageParams.getTagId()!=null){
//          article_id 1：n tag_id
//            queryWrapper的in方法
            LambdaQueryWrapper<ArticleTag> articleTagLambdaQueryWrapper=new LambdaQueryWrapper<>();
            articleTagLambdaQueryWrapper.eq(ArticleTag::getTagId,pageParams.getTagId());
            List<ArticleTag> articleTagList=articleTagDao.selectList(articleTagLambdaQueryWrapper);
            for (ArticleTag articleTag:articleTagList){
                articleIdList.add(articleTag.getArticleId());
            }
            if(articleIdList.size()>0){
                queryWrapper.in(Article::getId,articleIdList);
            }
        }

        queryWrapper.orderByDesc(Article::getCreateDate,Article::getWeight);//顺序order by create_data desc
        Page<Article> articlePage=articleDao.selectPage(page,queryWrapper); //分页查询用法
        List<Article> records=articlePage.getRecords();
        List<ArticleVo> articleVoList=copyList(records,true,true);
        return Result.success(articleVoList);

    }
//    mybatisplus不支持多表查询,支持单表查询

    @Override
    public Result hotAtricle(int limit) {
        LambdaQueryWrapper<Article> queryWrapper=new LambdaQueryWrapper<>();//包裹
        queryWrapper.orderByDesc(Article::getViewCounts);//顺序
        queryWrapper.last("limit "+limit);
        List<Article> articles=articleDao.selectList(queryWrapper);
        return Result.success(copyList(articles,false,false));
    }

    @Override
    public Result newAtricle(int limit) {
        LambdaQueryWrapper<Article> queryWrapper=new LambdaQueryWrapper<>();//包裹
        queryWrapper.orderByDesc(Article::getCreateDate);//顺序
        queryWrapper.last("limit "+limit);
        List<Article> articles=articleDao.selectList(queryWrapper);
        return Result.success(copyList(articles,false,false));
    }
    @Resource
    private ThreadService threadService;

    @Override
    public Result findArticleById(Long articleId) {
        /**
         * id 文章信息
         * bodyId和categoryId
         */

        Article article=articleDao.queryById(articleId);


        ArticleVo articleVo=copy(article,true,true,true,true);
        threadService.updateArticleViewCounts(articleDao,article);

        return Result.success(articleVo);


    }

    @Override
    public Result findArticleByKey(String key) {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();

        wrapper.and(w -> {
            for (char c : key.toCharArray()) {
                w.or().like(Article::getTitle, String.valueOf(c))
                        .or().like(Article::getSummary, String.valueOf(c));
            }
        });

        List<Article> list = articleDao.selectList(wrapper);
        return Result.success(list);
    }


    private List<ArticleVo> copyList(List<Article> records,boolean isTag,boolean isAuthor){
        List<ArticleVo> articleVoList=new ArrayList<>();
        for (Article record : records) {
            articleVoList.add(copy(record,isTag,isAuthor,false,false));

        }
        return articleVoList;
    }
    private List<ArticleVo> copyList(List<Article> records,boolean isTag,boolean isAuthor,boolean isBody,boolean isCategory){
        List<ArticleVo> articleVoList=new ArrayList<>();
        for (Article record : records) {
            articleVoList.add(copy(record,isTag,isAuthor,isBody,isCategory));

        }
        return articleVoList;
    }
    private ArticleVo copy(Article article,boolean isTag,boolean isAuthor,boolean isBody,boolean isCategory){
        ArticleVo articleVo=new ArticleVo();
        BeanUtils.copyProperties(article, articleVo);
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));
        if(isTag){
            articleVo.setTags(tagService.findTagsByArticleId(article.getId()));
        }
        if(isAuthor){
            String authorId=article.getAuthorId().toString();
            articleVo.setAuthor(userService.queryById(authorId).getNickname());
        }
        if(isBody){
            long bodyId=article.getBodyId();
            ArticleBody articleBody= articleBodyService.queryById(bodyId);
            ArticleBodyVo articleBodyVo=new ArticleBodyVo();
            articleBodyVo.setContent(articleBody.getContent());

            articleVo.setBody(articleBodyVo);

        }
        if(isCategory){
            Integer categoryId=article.getCategoryId();
            Category category=categoryService.queryById(categoryId);
            CategoryVo categoryVo=new CategoryVo();
            BeanUtils.copyProperties(category,categoryVo);

            articleVo.setCategory(categoryVo);


        }
        return articleVo;
    }


//    easycode生成



    @Override
    public Article queryById(Long id) {
        return this.articleDao.queryById(id);
    }

//    @Override
//    public Page<Article> queryByPage(Article article, PageRequest pageRequest) {
//        long total = this.articleDao.count(article);
//        return new PageImpl<>(this.articleDao.queryAllByLimit(article, pageRequest), pageRequest, total);
//    }

    @Override
    public Article insert(Article article) {
        this.articleDao.insert(article);
        return article;
    }




}
